import { select } from 'd3-selection'
import mitter from '@/mitt'
import { getTargetDataById, recursiveTreeValue } from '../utils'

let imageControlName = null

export function graphNodeImages (nodeContainer) {
  nodeContainer
    .selectAll('.x-mind-nodetheme')
    .select('.xmind-node-image')
    .remove()

  nodeContainer
    .selectAll('.x-mind-nodetheme')
    .filter(n => n.data.imageInfo)
    .append('g')
    .attr('class', 'xmind-node-image')
    .on('dblclick', event => event.stopPropagation())
    .append('image')
    .attr('x', d => d.x + (d.width - d.data.imageInfo.width) / 2)
    .attr('y', d => d.y + d.style.margin._t)
    .attr('width', d => d.data.imageInfo.width)
    .attr('height', d => d.data.imageInfo.height)
    .attr('xlink:href', d => d.data.imageInfo.url)
    .on('click', function (event) {
      imageHandlerClick(event, this)
      mitter.emit('image-handler-click')
    })
}

export function imageControlPointMove (event) {
  if (!imageControlName) return
  const controlNode = select('.element-drag-controller')
  const imageNode = controlNode.select('image')
  const x = Number(imageNode.attr('x'))
  const y = Number(imageNode.attr('y'))
  const width = Number(imageNode.attr('width'))
  const height = Number(imageNode.attr('height'))
  const ratio = width / height
  let [startX, startY, currentWidth] = [0, 0, 0]
  const pointClientRect = controlNode.select(`.${imageControlName}`).node().getBoundingClientRect()
  if (event.x > pointClientRect.x && event.movementX <= 0) return
  if (event.x < pointClientRect.x && event.movementX >= 0) return
  if (imageControlName.includes('top-left')) {
    // 左上角控制点拖动
    startX = x + event.movementX
    startY = y + event.movementX / ratio
    currentWidth = width - event.movementX
  } else if (imageControlName.includes('top-right')) {
    // 右上角控制点拖动
    startX = x
    startY = y - event.movementX / ratio
    currentWidth = width + event.movementX
  } else if (imageControlName.includes('bottom-right')) {
    // 右下角控制点拖动
    startX = x
    startY = y
    currentWidth = width + event.movementX
  } else {
    // 左下角控制点拖动
    startX = x + event.movementX
    startY = y
    currentWidth = width - event.movementX
  }
  const currentHeight = currentWidth / ratio
  if (currentWidth <= 20 || currentHeight <= 20 || currentWidth >= 800) {
    return
  }
  controlNode
    .select('path')
    .attr('d', `M${startX} ${startY} H${startX + currentWidth} V${startY + currentHeight} H${startX} V${startY}`)
  controlNode
    .select('image')
    .attr('x', startX)
    .attr('y', startY)
    .attr('width', currentWidth)
    .attr('height', currentHeight)
  controlNode.select('.top-left-point').attr('x', startX - 4).attr('y', startY - 4)
  controlNode.select('.top-right-point').attr('x', startX + currentWidth - 4).attr('y', startY - 4)
  controlNode.select('.bottom-right-point').attr('x', startX + currentWidth - 4).attr('y', startY + currentHeight - 4)
  controlNode.select('.bottom-left-point').attr('x', startX - 4).attr('y', startY + currentHeight - 4)
}

export function imageHandlerClick (event, _this) {
  event.stopPropagation()
  const imageNode = select(_this)
  const x = Number(imageNode.attr('x'))
  const y = Number(imageNode.attr('y'))
  const width = Number(imageNode.attr('width'))
  const height = Number(imageNode.attr('height'))
  const controlNode = select('.element-drag-controller')
    .attr('data-id', select(_this.parentNode.parentNode).attr('id'))
    .raise()
    .style('display', 'block')
  controlNode.select('image').remove()
  controlNode
    .select('path')
    .attr('d', `M${x} ${y} H${x + width} V${y + height} H${x} V${y}`)
  controlNode.select('.top-left-point').attr('x', x - 4).attr('y', y - 4)
  controlNode.select('.top-right-point').attr('x', x + width - 4).attr('y', y - 4)
  controlNode.select('.bottom-right-point').attr('x', x + width - 4).attr('y', y + height - 4)
  controlNode.select('.bottom-left-point').attr('x', x - 4).attr('y', y + height - 4)
  controlNode
    .insert(() => imageNode.clone().node(), 'path')
    .attr('opacity', 0.4)
  controlNode.selectAll('.control-point')
    .on('mousedown', function (event) {
      event.stopPropagation()
      const svg = select('#zx-xmind-map-svg')
      imageControlName = select(this).attr('class').split(' ')[0]
      if (['top-left-point', 'bottom-right-point'].includes(imageControlName)) {
        svg.classed('nw-resize', true)
      } else {
        svg.classed('ne-resize', true)
      }
    })
}

export function imageControlMoveEnd (root, callback) {
  if (!imageControlName) return
  const id = select('.element-drag-controller').attr('data-id')
  const width = Number(select('.element-drag-controller image').attr('width'))
  const height = Number(select('.element-drag-controller image').attr('height'))
  const data = getTargetDataById(root, id)
  data.imageInfo.width = width
  data.imageInfo.height = height
  imageControlName = null
  callback && callback()
}

export function deleteTopicImage (root, callback) {
  if (select('.element-drag-controller').style('display') === 'block') {
    const id = select('.element-drag-controller').attr('data-id')
    recursiveTreeValue(root, id, 'imageInfo', null)
    callback && callback()
  }
}
